package main

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
)

// curl --location --request POST 'https://api.coze.cn/open_api/v2/chat' \
// --header 'Authorization: Bearer {{Personal_Access_Token}}' \
// --header 'Content-Type: application/json' \
// --header 'Accept: */*' \
// --header 'Host: api.coze.cn' \
// --header 'Connection: keep-alive' \
// --data-raw '{
//     "conversation_id": "123",
//     "bot_id": "{{Bot_Id}}",
//     "user": "123333333",
//     "query": "{{yourquery}}",
//     "stream":false
// }'

type Value struct {
	Content string `json:"content"`
	Image   string `json:"image"`
	Title   string `json:"title"`
}

type MessageContent struct {
	Variables struct {
		Data struct {
			DefaultValue []Value `json:"defaultValue"`
		} `json:"data"`
	} `json:"variables"`
}

type ContextData struct {
	Data string `json:"data"`
}

type Message struct {
	Role        string `json:"role"`
	Type        string `json:"type"` // 当 role=assistant 时，用于标识 Bot 的消息类型，取值：
	Content     string `json:"content"`
	ContentType string `json:"content_type"`
}

type ResponseBody struct {
	ConversationID string    `json:"conversation_id"`
	Messages       []Message `json:"messages"`
	Code           int       `json:"code"`
	Msg            string    `json:"msg"`
}

func main() {
	conversationID := "123"
	user := "456"
	query := "龟兔晒跑的故事"
	result, err := doRequest(conversationID, query, user)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(result)
}

func doRequest(conversationID, query, user string) ([]Value, error) {
	url := CozeURL
	// BotID := "7375808933808308250"
	BotID := "7384252421830230079" // 相册
	var requestBody = struct {
		ConversationID string `json:"conversation_id"`
		BotID          string `json:"bot_id"`
		User           string `json:"user"`
		Query          string `json:"query"`
		Stream         bool   `json:"stream"`
	}{
		ConversationID: conversationID,
		BotID:          BotID,
		User:           user,
		Query:          query,
		Stream:         false,
	}
	values := []Value{}
	body, err := json.Marshal(requestBody)
	if err != nil {
		return values, err
	}
	request, err := http.NewRequestWithContext(context.Background(), http.MethodPost, url, bytes.NewBuffer(body))
	if err != nil {
		log.Panicf("new request error: %v", err)
	}
	request.Header.Set("Authorization", "Bearer "+token)
	request.Header.Set("Content-Type", "application/json")
	request.Header.Set("Accept", "*/*")
	request.Header.Set("Host", "api.coze.cn")
	request.Header.Set("Connection", "keep-alive")
	request.Header.Set("Authorization", "Bearer "+token)
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		return values, err
	}

	bodyByte, err := io.ReadAll(response.Body)
	if err != nil {
		return values, err
	}
	var respBody ResponseBody
	if err := json.Unmarshal(bodyByte, &respBody); err != nil {
		return values, err
	}

	defer response.Body.Close()
	if respBody.Code != 0 {
		return values, errors.New(respBody.Msg)
	}
	// List<Object>
	var content = ""
	for _, message := range respBody.Messages {
		if message.Type == "answer" && message.Role == "assistant" && message.ContentType == "card" {
			// 获取助手回复
			// log.Printf("assistant answer \n %+v", message.Content)
			// msgByte, _ := json.MarshalIndent(message, "", "  ")
			// log.Printf("response message:\n %s", string(msgByte))
			content = message.Content
			break
		}
	}

	var messageContent MessageContent
	if err := json.Unmarshal([]byte(content), &messageContent); err != nil {
		return values, err
	}

	// msgByte, _ := json.MarshalIndent([]byte(content), "", "  ")
	// log.Printf("response message:\n %s", string(msgByte))
	// log.Printf("messageContent:\n %v", messageContent)
	var cData ContextData
	if err := json.Unmarshal([]byte(content), &cData); err != nil {
		return values, err
	}

	var msgContent MessageContent
	if err := json.Unmarshal([]byte(cData.Data), &msgContent); err != nil {
		return values, err
	}
	return msgContent.Variables.Data.DefaultValue, nil
}
